from .global_var import Type_Ins

class Instruction(object):
    """
    调度系统的输出：对某一车辆的指令
    - aiv_id 执行该指令的AIV编号
    - ins_type 动作指令类型，分为发车指令、加减速指令、充电指令
    - info 字典的形式返回该指令对象的所有属性及对应的值
    """

    def __init__(self, ins_type, aiv_id):
        self.aiv_id = aiv_id
        self.ins_type = ins_type
        self.__values = {}
    
    def __getitem__(self, key: str):
        return self.__values[key]

    def __setitem__(self, key: str, value) -> None:
        self.__values[key] = value

    @property
    def info(self):
        """
        对象转化为字典
        """
        dict_self = vars(self)
        dict_self['ins_type'] = self.ins_type.name
        dict_self.pop('_Instruction__values')
        return dict_self
    
    def print(self):
        print(self.info)


class InsTask(Instruction):
    """
    任务分配指令，任务分配时产出，具有以下只读属性
    - aiv_id 执行该指令的AIV编号
    - ins_type 动作指令类型，分为发车指令、加减速指令、充电指令
    - task_id 匹配的任务id
    - time_start 发车执行该任务的时间
    - time_spent 到达 destination 大概需要的时间
    - first_target 取货点
    - second_target 卸货点
    - destination 到达这一点代表当前任务完成
    """
    def __init__(self, aiv, task, distance):
        """
        初始化时为AIV分配任务，计算各种时间点
        """
        super().__init__(Type_Ins.Task, aiv['id'])
        self.task_id = task.id
        self.time_spent = round(distance / aiv['velocity'], 1)
        self.time_start = round(task.start_time - self.time_spent, 1)
        self.pos_start = aiv['position']
        self.first_target = task.start_pos
        self.second_target = task.end_pos

    @property
    def origin(self):
        """
        任务的起点
        """
        return self.first_target

    @property
    def destination(self):
        """
        任务的终点
        """
        if self.second_target:
            return self.second_target
        return self.first_target
        
    @property
    def path(self):
        return self.second_target
    

class InsDeparture(Instruction):
    """
    立即发车指令，单车调度时的产出
    - aiv_id 执行该指令的AIV编号
    - ins_type 动作指令类型，分为发车指令、加减速指令、充电指令
    - destination 此次发车去哪里
    """
    def __init__(self, aiv, destination, signal):
        """
        某一AIV，按照某一路径去走
        """
        super().__init__(Type_Ins.Departure, aiv['id'])
        self.destination = destination
        self.origin = aiv['position']
        self.signal = signal


class InsAction(Instruction):
    """
    动作指令，加减速指令
    - aiv_id 执行该指令的AIV编号
    - ins_type 动作指令类型（在此为动作指令）
    - action 做什么动作，加速或者减速
    - duration 这个动作做多久，时间
    """
    def __init__(self, aiv, action, time):
        """
        某一AIV，做某一动作，这个动作做多久
        """
        super().__init__(Type_Ins.Action, aiv['id'])
        pass